package com.dp.mallchat.common.chat.service.strategy;

import com.dp.mallchat.common.chat.dao.MessageDao;
import com.dp.mallchat.common.chat.domain.entity.Message;
import com.dp.mallchat.common.chat.domain.entity.Room;
import com.dp.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.dp.mallchat.common.chat.domain.vo.req.msg.MessageExtra;
import com.dp.mallchat.common.chat.domain.vo.req.msg.TextMsgReq;
import com.dp.mallchat.common.chat.domain.vo.resp.msg.TextMsgResp;
import com.dp.mallchat.common.chat.service.cache.RoomCache;
import com.dp.mallchat.common.common.utils.AssertUtil;
import com.dp.mallchat.common.common.utils.discover.PrioritizedUrlDiscover;
import com.dp.mallchat.common.common.utils.discover.UrlDiscover;
import com.dp.mallchat.common.user.domain.user.entity.User;
import com.dp.mallchat.common.user.domain.user.enums.RoleEnum;
import com.dp.mallchat.common.user.sensitive.SensitiveWordsBs;
import com.dp.mallchat.common.user.sensitive.SensitiveWordsFilter;
import com.dp.mallchat.common.user.service.RoleService;
import com.dp.mallchat.common.user.service.cache.UserInfoCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: dupeng
 * @CreateTime: 2024-06-28  17:04
 * @Description: 文本消息
 */
@Component
public class TextMsgHandler extends AbstractMsgHandler<TextMsgReq> {

    public static final int MAX_GAP = 100;
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private UserInfoCache userInfoCache;
    @Autowired
    private RoleService roleService;
    @Autowired
    private SensitiveWordsBs sensitiveWordsBs;

    //url卡片解析
    private static final UrlDiscover URL_DISCOVER = new PrioritizedUrlDiscover();

    @Override
    MessageTypeEnum getMsgType() {
        return MessageTypeEnum.TEXT;
    }

    /**
     * 子类扩展保存
     *
     * @param message 消息
     * @param body    请求对象
     */
    @Override
    protected void saveMsg(Message message, TextMsgReq body) {
        Message update = new Message();
        update.setId(message.getId());
        update.setContent(sensitiveWordsBs.filter(body.getContent()));
        update.setReplyMsgId(body.getReplyMsgId());

        // 扩展信息 extra
        MessageExtra extra = Optional.ofNullable(message.getExtra()).orElse(new MessageExtra());
        // 如果有at人，存入扩展消息
        if (!CollectionUtils.isEmpty(body.getAtUidList())) {
            extra.setAtUidList(body.getAtUidList());
        }

        // 如果有回复消息，维护本条消息与回复消息间隔多少条
        if (Objects.nonNull(body.getReplyMsgId())) {
            int gapCount = messageDao.getGapCount(message.getRoomId(), body.getReplyMsgId(), message.getId());
            update.setGapCount(gapCount);
            update.setReplyMsgId(body.getReplyMsgId());
        }
        // url识别跳转
        extra.setUrlContentMap(URL_DISCOVER.getUrlInfo(body.getContent()));

        update.setExtra(extra);
        messageDao.updateById(update);
    }

    @Override
    protected void checkMsg(TextMsgReq body, Long roomId, Long uid) {
        //检查回复消息
        if (Objects.nonNull(body.getReplyMsgId())) {
            Message message = messageDao.getById(body.getReplyMsgId());
            AssertUtil.isNotEmpty(message, "回复的消息不存在");
            AssertUtil.equal(message.getRoomId(), roomId, "只能回复同一房间消息");
        }

        //AT校验
        if (!CollectionUtils.isEmpty(body.getAtUidList())){
            //at人员是否在群聊，前端传递at人员可能重复，去重
            List<Long> atUidList = body.getAtUidList().stream().distinct().collect(Collectors.toList());
            Map<Long, User> batch = userInfoCache.getBatch(atUidList);
            //userInfoCache.保险起见，空值过滤
            long count = batch.values().stream().filter(Objects::nonNull).count();
            AssertUtil.equal(count, (long) atUidList.size(), "@用户不存在");

            //@all
            if (atUidList.contains(0L)){
                boolean isPower = roleService.hasPower(uid, RoleEnum.ADMIN);
                AssertUtil.isTrue(isPower, "没有权限@所有人");
                AssertUtil.equal(atUidList.size(), 1, "all不能和其他人同时@");
            }
        }

    }

    @Override
    public Object showMsg(Message msg) {
        TextMsgResp textMsgResp = new TextMsgResp();
        textMsgResp.setContent(msg.getContent());
        textMsgResp.setAtUidList(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getAtUidList).orElse(null));
        //父消息
        if (Objects.nonNull(msg.getReplyMsgId())) {
            Message replyMsg = messageDao.getById(msg.getReplyMsgId());
            TextMsgResp.ReplyMsg resReplyMsg = new TextMsgResp.ReplyMsg();
            resReplyMsg.setId(replyMsg.getId());
            resReplyMsg.setUid(replyMsg.getFromUid());
            resReplyMsg.setType(replyMsg.getType());
            resReplyMsg.setBody(MsgHandlerFactory.getStrategyNoNull(replyMsg.getType()).showReplyMsg(replyMsg));
            resReplyMsg.setCanCallback(msg.getGapCount() < MAX_GAP ? 1 : 0);
            resReplyMsg.setGapCount(msg.getGapCount());
            textMsgResp.setReply(resReplyMsg);
        }

        // url识别跳转
        textMsgResp.setUrlContentMap(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getUrlContentMap).orElse(null));
        return textMsgResp;
    }

    @Override
    public Object showReplyMsg(Message msg) {
        return msg.getContent();
    }

    @Override
    public String showContactMsg(Message msg) {
        return msg.getContent();
    }
}
